<template>
  <form class="cmp cmp-parse">
    <fieldset>
      <legend>参数设置</legend>
      <div class="fieldset-content">
        <div class="form-group form-item-row" align="center">
          <div class="form-item-label">文件</div>
          <div class="form-item-input"><input class="form-control" type="text" v-model="filePath" placeholder="请选择要解析的文件" readonly /></div>
          <div class="form-item-suffix"><x-button @click="setFilePath">选择...</x-button></div>
        </div>
        <div class="form-group form-item-row" align="center">
          <div class="form-item-label">导出位置</div>
          <div class="form-item-input"><input class="form-control" type="text" v-model="saveFilePath" placeholder="请选择文件处理后的存储位置" readonly /></div>
          <div class="form-item-suffix"><x-button @click="setSaveFilePath">选择...</x-button></div>
        </div>
        <div class="form-group form-item-row" align="center" v-if="targetFilePath">
          <div class="form-item-label">导出文件</div>
          <div class="form-item-input text-grey">{{ targetFilePath }}</div>
        </div>
        <div class="form-group form-group-main"></div>
        <div class="form-group form-item-row" align="center">
          <x-button type="primary" block @click="parse" :loading="loadingCount > 0">开始处理</x-button>
        </div>
      </div>
    </fieldset>
  </form>
</template>

<script>
const fs = global.require('fs')
const path = global.require('path')
const {remote} = global.require('electron')
const {dialog} = remote
const selfWindow= remote.getCurrentWindow()
const readFile = (filePath) => {
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (!err && data) {resolve(data)}
      else {reject('读取文件失败')}
    })
  })
}
const getHiddenFileIndex = (data) => {
  const sepData = new TextEncoder().encode('-sep-')
  const idx = data.findIndex((item, index) => {
    let count = 0
    for (let i = 0; i < sepData.length; i++) {
      if (data[index+i] === sepData[i]) { count++ }
    }
    if (count === sepData.length) { return true }
    return false
  })
  return idx === -1 ? idx : idx + sepData.length
}
const data2str = (data) => {
  return data.reduce((a, b) => a + String.fromCharCode(b), '').trim()
}

export default {
  name: 'parse',
  data () {
    return {
      filePath: '',
      saveFilePath: this.$sharedObject('desktopPath'),
      targetFilePath: '',
      loadingCount: 0,
    }
  },
  methods: {
    // 选择文件
    setFilePath () {
      let filePaths = dialog.showOpenDialogSync(selfWindow, {
        title: '选择文件',
        buttonLabel:'确定',
        defaultPath: this.$sharedObject('desktopPath'),
        properties: ['openFile']
      })
      if (filePaths instanceof Array && filePaths.length > 0) {
        this.filePath = filePaths[0]
      }
    },
    // 设置解密文件保存位置
    setSaveFilePath () {
      let filePaths = dialog.showOpenDialogSync(selfWindow, {
        title: '选择目录',
        buttonLabel:'确定',
        defaultPath: this.$sharedObject('desktopPath'),
        properties: ['openDirectory']
      })
      if (filePaths instanceof Array && filePaths.length > 0) {
        this.saveFilePath = filePaths[0]
      }
    },
    // 表单校验
    checkForm () {
      let result = true
      if (!this.filePath) {
        result = false
        this.$toast('文件地址不能为空')
      }
      return result
    },
    // 解析
    parse () {
      if (!this.checkForm()) return
      this.loadingCount++
      this.targetFilePath = ''
      readFile(this.filePath).then(mainFile => {
        if (!mainFile) { return this.$toast('文件加载失败') }
        let mainFileData = new Uint8Array(mainFile)
        let index = getHiddenFileIndex(mainFileData)
        if (index === -1) { return this.$toast('未找到隐藏文件') }

        let targetExtData = mainFileData.subarray(index, index + 4)
        let targetExt = data2str(targetExtData)
        let targetData = mainFileData.subarray(index + 4)
        let targetFilePath = path.join(this.saveFilePath, `parse_${Date.now()}.${targetExt}`)
        this.loadingCount++
        this.$sharedObject('jstoolsNode').writeFile(targetFilePath, Buffer.from(targetData)).then(() => {
          this.$toast('导出完成')
          this.targetFilePath = targetFilePath
        }).catch((err) => {
          this.$toast('导出错误：' + err)
        }).finally(() => {
          this.loadingCount--
        })
      }).finally(() => {
        this.loadingCount--
      })
    },
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";
.form-item-row {
  display: flex;
  .form-item-label {
    min-width: 4em;
    margin-right: .5em;
    text-align-last: justify;
  }
  .form-item-input {
    width: 0;
    flex-grow: 1;
    text-align: left;
  }
  .form-item-suffix {
    margin-left: .5em;
    min-width: 2em;
  }
  &[align="center"] {
    align-items: center;
  }
}
.cmp-parse {
  height: 100%;
  fieldset {
    height: 100%;
    .fieldset-content {
      height: calc(100% - 2em);
      display: flex;
      flex-direction: column;
      .form-group-main {
        height: 0;
        flex-grow: 1;
      }
    }
  }
}
</style>
